package name.huliqing.qfaces.temp;
///*
// * To change this template, choose Tools | Templates
// * and open the template in the editor.
// */
//
//package name.huliqing.qfaces.component;
// 
//import java.io.IOException;
//import java.util.Map;
//import java.util.logging.Logger;
//import java.util.regex.Pattern;
//import javax.el.MethodExpression;
//import javax.faces.component.EditableValueHolder;
//import javax.faces.component.UIComponent;
//import javax.faces.component.UIComponentBase;
//import javax.faces.context.FacesContext;
//import javax.faces.context.ResponseWriter;
//import javax.faces.convert.Converter;
//import name.huliqing.qfaces.QFaces;
///**
// * 
// * @author huliqing
// */
//public class ____20100703_Validator extends UIComponentBase implements Ajax{
//	private final static Logger logger = Logger.getLogger(____20100703_Validator.class.getName());
//	
//	// ---------------------------------------- 外部参数
//	
//	// 指定到当前组件所服务的目标组件，一般应该指定到inputText,inputHidden,
//	// inputTextarea,selectMany...,selectOne...等能够保存值的组件
//	// 也就是说，for的值应该为某个InputText...组件的id
//	private String _for;
//	
//	// 对于目标组件输入值的提示信息，如在用户注册帐号时，我们经常会这样提示用户：
//	// "请输入你的用户名，长度不能小于6个字符，并且不能大于30个字符",以帮助用户
//	// 输入正确的值。
//	private String message;
//
//	// 当验证出错时要显示的信息,如果不设置，则默认使用message
//	private String messageError;
//	
//	// 当验证正确时要显示的信息,如果不设置，则默认使用message
//	private String messageCorrect;
//	
//	// 定义允许填写的字符串最小长度
//	private Integer minLength;
//	
//	// 定义允许填写的字符串最大长度
//	private Integer maxLength;
//	
//	// 定义目标允许填的最小值,也就是目标值不能小于这个值
//	// 这个限制只有目标为数值类型，并且有填值时才有效.
//	// 你可以通过组件的required,type属性来配合这个属性,起到验证数字的作用
//	private Long min;
//	
//	// 定义目标允许填的最大值，也就是目标值不能大于这个值
//	// 这个限制只有目标为数值类型，并且有填值时才有
//	// 请参考属性“min"
//	private Long max;
//	
//	// 定义目标是否是必填值的
//	private Boolean required;
//	
//	// 定义目标的类型，该参数的取值必须为以下数据
//	// "String"		-> 任何字符
//	// "Number" 	-> 数字类型,不分正负，整数，小数
//	// "Integer"	-> 表示整数，不分正负，整数
//	private String type;
//	
//	// 指定到另一个目标组件ID，如果指定了equalId,那么这个组件的值必须
//	// 与equalId所指定的目标组件的值相等，这样才能通过验证。(equal是相等的意思，
//	// 不单指数字相等，字符也要完全相等)
//	private String equalId;
//	
//	// 正则表达式,该表达式用于验证目标组件值,通过正则表达式可以用
//	// 相对简单的表达式来达到其它简单属性所无法达到的验则规则,几个参考示例：<BR />
//	// ^[a-zA-Z]+$			-> 匹配所有英文字母
//	// ^[a-z]+$				-> 匹配所有小写英文字母
//	// ^[A-Z]+$				-> 匹配所有大写英文字母
//	// ^\d+$ 或 ^[0-9]+$		-> 匹配所有无符号的正整数。（阿拉伯数字）
//	// ^\+?\d+$				-> 匹配所有正整，（可带+号）
//	// ^\-\d+$				-> 匹配所有负整数（带-号）
//	// ^[0-9]*\.?[0-9]*$	-> 匹配所有无符号的浮点数
//	// ^\+?[0-9]*\.?[0-9]*$	-> 匹配所有浮点数（正数）
//	// ^\-[0-9]*\.?[0-9]*$	-> 匹配所有浮点数（负数）
//	private String regex;
//	
//	// 绑定到后台某个方法，方法签名应该像这样：public Boolean listener(String arg)
//	// 这个方法绑定主要是让用户能够以更高级的方式验证目标组件的值。该方法会以Ajax的方法将前台页
//	// 面目标组件的值通过Ajax方式传递到后台作为这个方法的参数(arg)，通过这个方法对
//	// 组件值进行验证，并返回true/false来确认目标组件的值是否允许,这属于前端验证
//	// 在生命周期的验证阶段，这个方法会再次调用（服务端验证），来保证目标组件的值是允许的
//	private MethodExpression listener;
//	
//	// 触发类型，该属性指定前端页面如何触发组件的验证。可指定的属性值如下：
//	// onblur -> 鼠标离开目标组件焦点时.
//	// interval -> 每间隔一个时间段验证一次 .
//	private String event;
//
//	// 当event属性指定为"interval"时，这个属性才有作用
//	// 这个属性用于指定interval验证方式时的时间间隔.这个属性不会导致无休止的验证,
//	// 每次要触发验证时都应该先检查当前目标组件值是否与最后一次验证时的值是否一致。
//	// 如果一致则不再验证，否则会造成 listener属性不停调用Ajax(如果设置了listener属性)
//	private Integer interval;
//	
//	// 绑定到JavaScript Function属性，当目标组件值被验证不通过时执行的javascript函数
//	private String onError;
//	
//	// 绑定到JavaScript Function属性，当目标组件值被验证通过时执行的javascript函数
//	private String onCorrect;
//	
//	// 是否显示图标,打开这个属性，可以让组件在验证正确或错误时显示一个不同的图标
//	// 通过imgSrcCorrect,imgSrcError属性可以指定这两个不同的图标
//	private Boolean displayFlag;
//	
//	// 当发生验证错误时，显示的图标的URL
//	private String imgSrcError;
//	
//	// 当发生验证正确时，显示的图标的URL
//	private String imgSrcCorrect;
//	
//	// Message的默认样式
//	private String styleClass;
//	
//	// 当发生验证错误时，message的样式
//	private String styleClassError;
//	
//	// 当发生验证正确时，message的样式
//	private String styleClassCorrect;
//	
//	// 当发生验证错误时，目标组件的样式
//	private String styleClassTargetError;
//	
//	// 当发生验证正确时， 目标组件的样式
//	private String styleClassTargetCorrect;
//	
//	// ---------------------------------------- 内部参数
//	
//	// 整个组件的ID
//	private String ID_CLIENT;
//	
//	// 组件Flag图标区域的ID
//	private String ID_FLAG;
//	
//	// 组件message的ID
//	private String ID_MESSAGE;
//	
//	// 该组件的当前状态,定义如下:
//	// -1	-> 发生验证错误的
//	// 0	-> 状态未知的，也就是未经过验证的
//	// 1	-> 经过验证为正确的
//	private Integer state;
//
//    @Override
//    public Object saveState(FacesContext fc) {
//    	Object[] obj = new Object[12];
//    	obj[0] = super.saveState(fc);
//    	obj[1] = listener;
//    	obj[2] = _for;
//    	obj[3] = message;
//    	obj[4] = minLength;
//    	obj[5] = maxLength;
//    	obj[6] = min;
//    	obj[7] = max;
//    	obj[8] = required;
//    	obj[9] = type;
//    	obj[10] = equalId;
//    	obj[11] = regex;
//    	return obj;
//    }
//    
//    @Override
//    public void restoreState(FacesContext fc, Object o) {
//    	Object[] obj = (Object[]) o;
//    	super.restoreState(fc, obj[0]);
//    	listener = (MethodExpression) obj[1];
//    	_for = (String) obj[2];
//    	message = (String) obj[3];
//    	minLength = (Integer) obj[4];
//    	maxLength = (Integer) obj[5];
//    	min = (Long) obj[6];
//    	max = (Long) obj[7];
//    	required = (Boolean) obj[8];
//    	type = (String) obj[9];
//    	equalId = (String) obj[10];
//    	regex = (String) obj[11];
//    }
//    
//    public MethodExpression getListener() {
//		return listener;
//	}
//
//	public void setListener(MethodExpression listener) {
//		this.listener = listener;
//	}
//
//	@Override
//    public void encodeBegin(FacesContext fc) throws IOException {
//		// 载入资源
//		QFaces.getResLoader2().loadJavaScript(this, "Validator.js");
//
//		// ---- 设定ID
//		
//    	this.ID_CLIENT = this.getClientId(fc);
//    	this.ID_FLAG = this.ID_CLIENT + ":flag";
//    	this.ID_MESSAGE = this.ID_CLIENT + ":message";
//    	
//    	// ---- 载入参数
//    	
//    	this._for = (String) this.getAttributes().get("for");
//    	this.message = (String) QFaces.getAttribute(this, "message", "");
//    	this.messageError = (String) QFaces.getAttribute(this, "messageError", this.message);
//    	this.messageCorrect = (String) QFaces.getAttribute(this, "messageCorrect", this.message);
//    	this.minLength = QFaces.convertToInteger(QFaces.getAttribute(this, "minLength", null));
//    	this.maxLength = QFaces.convertToInteger(QFaces.getAttribute(this, "maxLength", null));
//    	this.min = QFaces.convertToLong(QFaces.getAttribute(this, "min", null));
//    	this.max = QFaces.convertToLong(QFaces.getAttribute(this, "max", null));
//    	this.required = QFaces.convertToBoolean(QFaces.getAttribute(this, "required", Boolean.FALSE));
//    	this.type = (String) QFaces.getAttribute(this, "type", "String");
//    	this.equalId = (String) QFaces.getAttribute(this, "equalId", "");
//    	this.regex = (String) QFaces.getAttribute(this, "regex", "");
//    	this.event = (String) QFaces.getAttribute(this, "event", "onblur");
//    	this.interval = QFaces.convertToInteger(QFaces.getAttribute(this, "interval", 100)); // 默认100毫秒检测一次
//    	this.onError = (String) QFaces.getAttribute(this, "onError", "");
//    	this.onCorrect = (String) QFaces.getAttribute(this, "onCorrect", "");
//    	this.displayFlag = QFaces.convertToBoolean(QFaces.getAttribute(this, "displayFlag", Boolean.TRUE));
//    	this.imgSrcError = (String) QFaces.getAttribute(this, "imgSrcError", 
//    			QFaces.getResLoader2().makeImageSrc("05-error.gif"));
//    	this.imgSrcCorrect = (String) QFaces.getAttribute(this, "imgSrcCorrect", 
//    			QFaces.getResLoader2().makeImageSrc("05-correct.gif"));
//    	this.styleClass = (String) QFaces.getAttribute(this, "styleClass", "_qf_05_styleClass");
//    	this.styleClassError = (String) QFaces.getAttribute(this, "styleClassError", "_qf_05_styleClassError");
//    	this.styleClassCorrect = (String) QFaces.getAttribute(this, "styleClassCorrect", "_qf_05_styleClass"); // 与默认同一个样式
//    	this.styleClassTargetError = (String) QFaces.getAttribute(this, "styleClassTargetError", "");
//    	this.styleClassTargetCorrect = (String) QFaces.getAttribute(this, "styleClassTargetCorrect", "");
//    	
//    	// ---- 处理参数，确保参数正确
//    	if (this._for == null)
//    		throw new NullPointerException("The Attribute \"for\" required!");
//    	
//    	// 将for属性所指定的ID转化为长的客户端ID,找不到则不管，因为有可能为一般的HTML组件的ID
//    	UIComponent target = findComponent(this._for);
//    	if (target != null) 
//    		this._for = target.getClientId(fc);
//    	
//    	// 作用同上
//    	if (!this.equalId.equals("")) {
//    		UIComponent eqTarget = findComponent(this.equalId);
//    		if (eqTarget != null)
//    			this.equalId = eqTarget.getClientId(fc);
//    	}
//    	
//    	// 给予一些提示,或许用户忘记了设置message属性
//    	if (this.message.equals(""))
//    		logger.warning("Attribute \"message\" not found! use default value \"\".");
//    	
//    	// 首次渲染时一定处于未验证状态，在回传时可能就不一定
//    	if (this.state == null)
//    		this.state = 0;
//    	
//    	// 确保默认响应类型
//    	if (!"onblur".equalsIgnoreCase(this.event) && !"interval".equalsIgnoreCase(this.event)) 
//    		this.event = "onblur";
//    	
//    	// ---- 渲染
//    	
//    	ResponseWriter rw = fc.getResponseWriter();
//    	rw.startElement("span", this);
//    	rw.writeAttribute("id", this.ID_CLIENT, "id");
//    	rw.writeAttribute("style", "border:0px solid red;", null);
//
//    		// render flag
//    		rw.startElement("span", this);
//    		rw.writeAttribute("id", this.ID_FLAG, null);
//    		rw.writeAttribute("style", "vertical-align:middle;border:0px solid green;", null);
//    		rw.endElement("span");
//    		
//    		// render message
//    		rw.startElement("span", this);
//    		rw.writeAttribute("id", this.ID_MESSAGE, null);
//    		rw.writeAttribute("style", "border:0px solid blue;", null);
//    		rw.endElement("span");
//    	rw.endElement("span");
//    	
//    }
//	
//	@Override
//    public void encodeEnd(FacesContext fc) throws IOException {
//		
//		// init
//		
//		// Java与JavaScript的正则在“\”的转义上存在一些差异
//		String regexForJS = "";
//		if (regex.indexOf("\\") != -1) {
//			regexForJS = regex.replaceAll("\\\\", "\\\\\\\\");
//		} else {
//			regexForJS = regex;
//		}
//		
//        StringBuilder jsInit = new StringBuilder("Q.F.UIValidator.init(")
//        		.append(" \"" + this.getClass().getName() + "\"")
//                .append(",\"" + this.ID_CLIENT + "\"")
//                .append(",\"" + this.ID_FLAG + "\"")
//                .append(",\"" + this.ID_MESSAGE + "\"")
//                .append(",\"" + this.state + "\"")
//                .append(",\"" + this._for + "\"")
//                .append(",\"" + this.message + "\"")
//                .append(",\"" + this.messageError + "\"")
//                .append(",\"" + this.messageCorrect + "\"")
//                .append(",\"" + (this.minLength != null ? this.minLength : "") + "\"")
//                .append(",\"" + (this.maxLength != null ? this.maxLength : "") + "\"")
//                .append(",\"" + (this.min != null ? this.min : "") + "\"")
//                .append(",\"" + (this.max != null ? this.max : "") + "\"")
//                .append(",\"" + this.required.toString() + "\"")
//                .append(",\"" + this.type + "\"")
//                .append(",\"" + this.equalId + "\"")
//                .append(",\"" + regexForJS + "\"")
//                .append(",\"" + (this.listener != null ? this.listener.getExpressionString() : "") + "\"")
//                .append(",\"" + this.event + "\"")
//                .append(",\"" + this.interval + "\"")
//                .append(",\"" + this.onError + "\"")
//                .append(",\"" + this.onCorrect + "\"")
//                .append(",\"" + this.displayFlag.toString() + "\"")
//                .append(",\"" + this.imgSrcError + "\"")
//                .append(",\"" + this.imgSrcCorrect + "\"")
//                .append(",\"" + this.styleClass + "\"")
//                .append(",\"" + this.styleClassError + "\"")
//                .append(",\"" + this.styleClassCorrect + "\"")
//                .append(",\"" + this.styleClassTargetError + "\"")
//                .append(",\"" + this.styleClassTargetCorrect + "\"")
//                .append(")");
//        QFaces.getResLoader2().loadJavaScriptInit(this, jsInit.toString());
//	}
//	
//	public void ajax(Map<String, String> params, FacesContext fc) {
//        String listenerExp = params.get("listenerExp");
//        String targetValue = params.get("targetValue");
//        Boolean result = this.validateListener(fc, targetValue, listenerExp);
//        QFaces.getResponse().responseHTML(fc, result.toString());
//	}
//	
//	@Override
//	public void decode(FacesContext fc) {
//		super.decode(fc);
//	}
//	
//	// 获取某个目标组件的表单提交值
//	private String getSubmitValue(FacesContext fc, String componentId) {
//		if (isNoValue(componentId))
//			return null;
//		
//		UIComponent targetUI = findComponent(componentId);
//		if (targetUI == null)
//			return null;
//
//		if (!(targetUI instanceof EditableValueHolder)) {
//			throw new RuntimeException("Not a EditableValueHolder component!" +
//					"目标组件必须是能够保存值的,如那些继承自" +
//					"EditableValueHolder的组件，InputText,SelectOne...等");
//		}
//		String resultValue = null;
//		EditableValueHolder holder = (EditableValueHolder) targetUI;
//		// 先获取value(可能是已经通过验证的了),如果不存在value,则获取submitValue
//		Object value = holder.getValue();
//		Object submitValue = holder.getSubmittedValue();
//		if (value != null) {
//			// 如果目标组件存在转换器，则需要将目标值转换回去(String)
//			// 这样才能与页面js的验证方式同步
//			Converter con = holder.getConverter();
//			if (con != null)
//				resultValue = con.getAsString(fc, targetUI, value);
//			else
//				resultValue = value.toString();
//		} else if(submitValue != null) {
//			resultValue = submitValue.toString();
//		}
//		return resultValue;
//	}
//	
//	// 获取_for所指定的目标组件的表单提交值
//	private String getTargetSubmitValue(FacesContext fc) {
//		return getSubmitValue(fc, this._for);
//	}
//	
//	// 获取EqualId所指定的目标组件的表单提交值
//	private String getEqualSubmitValue(FacesContext fc) {
//		return getSubmitValue(fc, this.equalId);
//	}
//	
//	@Override
//	public void processValidators(FacesContext fc) {
//		super.processValidators(fc);
//		String targetSubmitValue = getTargetSubmitValue(fc);
//		
//		// ---- validate
//		
//		// v1.
//		if (!validateRequired(targetSubmitValue)) {
//			logger.info("failure -> validateRequired");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateRequired");
//		
//		if (!validateLength(targetSubmitValue)) {
//			logger.info("failure -> validateLength");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateLength");
//		
//
//		if (!validateEqual(fc, targetSubmitValue)) {
//			logger.info("failure -> validateEqual");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateEqual");
//		
//		if (!validateRegex(targetSubmitValue)) {
//			logger.info("failure -> validateRegex");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateRegex");
//		
//		if (!validateType(targetSubmitValue)) {
//			logger.info("failure -> validateType");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateType");
//		
//		if (!validateVolume(targetSubmitValue)) {
//			logger.info("failure -> validateVolume");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateVolume");
//		
//		if (listener != null 
//				&& !validateListener(fc, targetSubmitValue, listener.getExpressionString())) {
//			logger.info("failure -> validateListener");
//			this.state = -1;
//			fc.renderResponse();
//			return;
//		}
//		logger.info("pass -> validateListener");
//		
//		// 通过验证
//		this.state = 1;
//	}
//	
//	// 验证两个值是否一致,只比较字符是否一样。
//	// 如果equalId为null或空，则不验证（返回true)
//	private boolean validateEqual(FacesContext fc, String targetValue) {
//		if (isNoValue(equalId))
//			return true;
//		String equalValue = getEqualSubmitValue(fc);
//		String hasValue = targetValue != null ? targetValue : equalValue;
//		// 同为null
//		if (hasValue == null)
//			return true;
//		return (hasValue.equals(targetValue) && hasValue.equals(equalValue));
//	}
//	
//	// 根据组件绑定的length属性来验证目标组件的值是否在长度限制之内
//	// 如果targetValue为null,则返回true
//	private boolean validateLength(String targetValue) {
//		if (isNoValue(targetValue))
//			return true;
//		if (minLength != null && targetValue.length() < minLength)
//			return false;
//		if (maxLength != null && targetValue.length() > maxLength)
//			return false;
//		return true;
//	}
//	
//	// 根据组件绑定的Listener来验证值是否正确
//	private boolean validateListener(FacesContext fc, String targetValue, String listenerExp) {
//		if (isNoValue(targetValue))
//			return true;
//		MethodExpression _listener = QFaces.createMethodExpression(listenerExp,
//                Boolean.class,
//                new Class[]{String.class});
//		Object[] args = {targetValue};
//		Boolean result = (Boolean) _listener.invoke(fc.getELContext(), args);
//		// 如果绑定的listener返回null,则默认认为通过验证
//		if (result == null)
//			result = true;
//		return result;
//	}
//	
//	// 根据组件所设定的正则表达式来验证目标值是否匹配
//	// 如果regex为null或空，则返回true
//	// 如果targetValue为null或空，则返回true
//	private boolean validateRegex(String targetValue) {
//		logger.info("regex=" + regex);
//		if (isNoValue(regex) || isNoValue(targetValue))
//			return true;
//		return Pattern.compile(regex).matcher(targetValue).matches();
//	}
//	
//	// 根据组件所设定的required属性来验证目标组件的值
//	// 如果required没有设置，则返回true
//	private boolean validateRequired(String targetValue) {
//		if (required != null && required) {
//			return (!isNoValue(targetValue));			
//		}
//		return true;
//	}
//	
//	// 根据组件所设定的type属性来验证目标组件的值是否符合要求
//	// 如果目标值targetValue为null或空，则不验证（返回true)
//	// 如果type=null或空,则不验证(返回true)
//	private boolean validateType(String targetValue) {
//		if (isNoValue(targetValue) || isNoValue(type))
//			return true;
//		if (type.equalsIgnoreCase("Integer")) {
//			return isInteger(targetValue);
//		} else if (type.equalsIgnoreCase("Number")) {
//			return isNumber(targetValue);
//		}
//		// Other case 3, type = String
//		return true;
//	}
//	
//	// 根据组件所设定的min,max属性来验证目标组件的值是否符合要求
//	// 该方法只判断数字类型，
//	// 如果目标值不能转换为数字，则不验证（返回true）
//	// 如果目标值为null或空，则不验证（返回true)
//	private boolean validateVolume(String targetValue) {
//		if (isNoValue(targetValue))
//			return true;
//		if (isInteger(targetValue)) {
//			Long temp = Long.parseLong(targetValue);
//			if (min != null && temp < min) 
//				return false;
//			if (max != null && temp > max)
//				return false;
//		} else if (isNumber(targetValue)) {
//			Double temp = Double.parseDouble(targetValue);
//			if (min != null && temp < min) 
//				return false;
//			if (max != null && temp > max)
//				return false;
//		}
//		return true;
//	}
//	
//	// 判断是否为null或者空
//	private boolean isNoValue(String targetValue) {
//		return (targetValue == null || "".equals(targetValue));
//	}
//	
//	private boolean isNumber(String targetValue) {
//		return Pattern.compile("^-?\\d*\\.?\\d+$").matcher(targetValue).matches();
//	}
//	
//	private boolean isInteger(String targetValue) {
//		return Pattern.compile("^-?\\d+$").matcher(targetValue).matches();
//	}
//	
//	@Override
//	public String getFamily() {
//		return getClass().getName();
//	}
//}
//
//
//
//
//
//
